package com.hc.race.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hc.race.contants.RabbitMqContants;
import com.hc.race.entity.Challenges;
import com.hc.race.entity.Progress;
import com.hc.race.entity.Users;
import com.hc.race.mapper.ProgressMapper;
import com.hc.race.service.ChallengeService;
import com.hc.race.service.ProgressService;
import com.hc.race.service.UsersService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;

import static com.hc.race.contants.RedisContants.USER_TASK;

/**
 * @Author zy
 * @Date 2023/11/25 9:42
 * @PackageName:com.hc.race.service.impl
 * @ClassName: ProgressServiceImpl
 * @Description: TODO
 * @Version 1.0
 */
@Service
@Slf4j
public class ProgressServiceImpl extends ServiceImpl<ProgressMapper,Progress> implements ProgressService {

    @Autowired
    private ChallengeService challengeService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ProgressMapper progressMapper;

    @Autowired
    private UsersService usersService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public Progress getDayInfo(Long userId,Long taskId) {
        String key = USER_TASK + userId + taskId;
        Challenges challenge = challengeService.getSingleInfo(taskId);
        LocalDateTime createTime = challenge.getCreateTime();
        LocalDateTime now = LocalDateTime.now();
        // 4.获取今天第几天
        long daysBetween = ChronoUnit.DAYS.between(createTime, now);
        int daysBetweenInt = Math.toIntExact(daysBetween)+1;
        List<Long> list = redisTemplate.opsForValue().bitField(key, BitFieldSubCommands.create()
                .get(BitFieldSubCommands.BitFieldType.unsigned(daysBetweenInt)
                ).valueAt(0)
        );
        if(list==null||list.isEmpty()){
            log.error("没有数据1");
        }

        Long num=list.get(0);
        System.out.println("num:"+num);
        if(num==null||num==0){
            log.error("没有数据2");
        }

        int index = 0;
        // 计算位数
        String binaryString = Long.toBinaryString(num);
        int length = binaryString.length();
        System.out.println("位数:"+length);
        // 从最左边开始找到第一个为0的位置
        while (index < length && ((num >> (length - 1 - index)) & 1) == 1) {
            index++;
        }
        System.out.println("第一个0:"+index);
////        没有找到一个0意味着都打卡了
        if(index==length-1){
            Progress progress=Progress.builder()
                    .percentage(0)
                    .day(index+1)
                    .number(0L)
                    .taskId(taskId)
                    .userId(userId)
                    .createTime(createTime)
                    .build();
            progressMapper.insert(progress);
            return progress;
        }
//        第一天没有打卡
        QueryWrapper<Progress> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId)
                .eq("task_id",taskId)
                .eq("day",index+1);
        Progress progress = progressMapper.selectOne(queryWrapper);
        if(progress==null){
                 progress=Progress.builder()
                    .percentage(0)
                    .day(index+1)
                    .number(0L)
                    .taskId(taskId)
                    .userId(userId)
                    .createTime(createTime)
                    .build();
            progressMapper.insert(progress);
        }
        return progress;
    }

    @Override
    public void success(Progress progress) {
        temp(progress);
        Long userId = progress.getUserId();
        Long taskId = progress.getTaskId();
        String key = USER_TASK + userId + taskId;
        Integer day = progress.getDay();
        System.out.println(day);
        redisTemplate.opsForValue().setBit(key,day-1,true);
    }

    @Override
    public void temp(Progress progress) {
        Long id = progress.getId();
        // 根据 id 查询数据库
        Progress existingProgress = progressMapper.selectById(id);

        if (existingProgress != null) {
            // 如果数据库中已经存在数据，则进行修改操作
            // 更新 existingProgress 的相关属性
            existingProgress.setNumber(progress.getNumber());
            existingProgress.setCreateTime(progress.getCreateTime());
            existingProgress.setPercentage(progress.getPercentage());
            progressMapper.updateById(existingProgress);
        } else {
            // 如果数据库中不存在数据，则进行新增操作
            progressMapper.insert(progress);
        }
    }

    @Override
    public void sendEmailToFriend(Long userId, Long friendId, Long taskId) {
        Users user = usersService.getInfo(userId);
        Users friend = usersService.getInfo(friendId);
        Challenges singleInfo = challengeService.getSingleInfo(taskId);
        String email=friend.getEmail();
        sendEmail2(email,user.getUsername(),singleInfo.getTaskName());
    }
    public void sendEmail1(String email) {
        try{
            String exchangeName = RabbitMqContants.EXCHANGE_NAME_REMID;
            String routingKey = RabbitMqContants.INSERT_KEY_REMID;
            String value = email+":"+"您今天还没有打卡";
            rabbitTemplate.convertAndSend(exchangeName,routingKey,value);
        }catch (Exception e){
            log.error("提醒失败");
        }
    }

    @Scheduled(cron = "0 * * * * ?")
    public void sendEmailReminders() {
        // 构建查询条件
        QueryWrapper<Progress> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("percentage", 100);

        // 查询数据库，获取percentage不为100的记录
        List<Progress> progressList = progressMapper.selectList(queryWrapper);

        // 遍历记录，发送提醒邮件
        for (Progress progress : progressList) {
           Long userId=progress.getUserId();
            Users user = usersService.getInfo(userId);
            String email=user.getEmail();
            sendEmail1(email);
        }
    }



    public void sendEmail2(String email,String username,String taskName) {
        try{
            String exchangeName = RabbitMqContants.EXCHANGE_NAME_REMID;
            String routingKey = RabbitMqContants.INSERT_KEY_REMID;
            String value = email+":"+username+"提醒您和他"+taskName+"的挑战今天还没有打卡";
            rabbitTemplate.convertAndSend(exchangeName,routingKey,value);
        }catch (Exception e){
            log.error("提醒失败");
        }
    }
}
